<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>绘制线框立方体</title>
    <style>
      body {
        display: flex;
        justify-content: center;
        align-items: center;
        height: 100vh;
        background-color: #f0f0f0;
      }
      canvas {
        border: 1px solid #ccc;
      }
    </style>
  </head>
  <body>
    <canvas id="canvas" width="500" height="500"></canvas>
    <!-- 顶点着色器 -->
    <script id="vertex-shader" type="x-shader/x-vertex">
      attribute vec4 aPosition; // 位置坐标
      uniform mat4 u_x_matrix; // x轴方向的旋转矩阵
      uniform mat4 u_y_matrix; // y轴方向的旋转矩阵
      void main() {
        gl_Position = u_x_matrix * u_y_matrix * aPosition;  // 正确应用旋转矩阵
        gl_PointSize = 10.0; // 设置点的大小
      }
    </script>

    <!-- 片元着色器 -->
    <script id="fragment-shader" type="x-shader/x-fragment">
      precision mediump float; // 设置精度
      uniform vec4 uColor; // 颜色变量
      void main() {
        gl_FragColor = uColor; // 设置颜色
      }
    </script>
    <script type="module">
      /*
              window.requestAnimationFrame() 是一个浏览器提供的函数，用于在下次重绘之前执行指定的函数。
              它通常用于创建动画效果，因为它可以在浏览器的刷新率下平滑地更新动画。
            */
      import initShaders from "../utils/initShader.js";

      const canvas = document.getElementById("canvas");
      const gl = canvas.getContext("webgl");
      if (!gl) {
        console.error("WebGL not supported");
      }

      const program = initShaders(gl);

      // 定义8个顶点（立方体）
      const vertices = new Float32Array([
        // -0.8,
        // -0.8,
        // 0.5, // 0 左下前
        // 0.8,
        // -0.8,
        // 0.5, // 1 右下前
        // 0.8,
        // 0.8,
        // 0.5, // 2 右上前
        // -0.8,
        // 0.8,
        // 0.5, // 3 左上前
        // 前面四个顶点
        -0.5,
        -0.5,
        0.5, // 0 左下前
        0.5,
        -0.5,
        0.5, // 1 右下前
        0.5,
        0.5,
        0.5, // 2 右上前
        -0.5,
        0.5,
        0.5, // 3 左上前

        // 后面四个顶点
        -0.5,
        -0.5,
        -0.5, // 4 左下后
        0.5,
        -0.5,
        -0.5, // 5 右下后
        0.5,
        0.5,
        -0.5, // 6 右上后
        -0.5,
        0.5,
        -0.5, // 7 左上后
      ]);

      // 定义索引（每个面2个三角形，共6个索引/面）
      const indices = new Uint16Array([
        // 前面（红色）
        0, 1, 2, 0, 2, 3,

        // 后面（绿色）
        4, 6, 5, 4, 7, 6,

        // 上面（蓝色）
        3, 2, 6, 3, 6, 7,

        // 下面（黄色）
        0, 5, 1, 0, 4, 5,

        // 右面（品红）
        1, 5, 6, 1, 6, 2,

        // 左面（青色）
        0, 3, 7, 0, 7, 4,
      ]);

      // 创建并绑定缓冲区
      const vertexBuffer = gl.createBuffer();
      gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
      gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

      const indexBuffer = gl.createBuffer();
      gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
      gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);

      // 获取属性位置
      const aPosition = gl.getAttribLocation(program, "aPosition");
      gl.vertexAttribPointer(
        aPosition,
        3,
        gl.FLOAT,
        false,
        3 * Float32Array.BYTES_PER_ELEMENT,
        0
      );
      gl.enableVertexAttribArray(aPosition);

      // 启用深度测试
      gl.enable(gl.DEPTH_TEST); // 启用深度测试，避免绘制顺序导致错误遮挡
      gl.disable(gl.CULL_FACE); // 禁用面剔除，确保所有面都被绘制
      // gl.depthFunc(gl.LESS);
      // gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

      // 设置颜色 uniform
      const uColor = gl.getUniformLocation(program, "uColor");

      // 每个面的颜色
      const faceColors = [
        [1.0, 0.0, 0.0, 1.0], // 前面：红色 ✅
        [0.0, 1.0, 0.0, 1.0], // 后面：绿色
        [0.0, 0.0, 1.0, 1.0], // 上面：蓝色
        [1.0, 1.0, 0.0, 1.0], // 下面：黄色
        [1.0, 0.0, 1.0, 1.0], // 右面：品红
        [0.0, 1.0, 1.0, 1.0], // 左面：青色
      ];

      // 循环绘制每个面
      for (let i = 0; i < faceColors.length; i++) {
        gl.uniform4fv(uColor, faceColors[i]);
        gl.drawElements(
          gl.TRIANGLES,
          6,
          gl.UNSIGNED_SHORT,
          i * 6 * Uint16Array.BYTES_PER_ELEMENT
        );
      }
      const u_x_matrix = gl.getUniformLocation(program, "u_x_matrix"); // 获取x轴旋转矩阵的uniform变量位置
      const u_y_matrix = gl.getUniformLocation(program, "u_y_matrix"); // 获取y轴旋转矩阵的uniform变量位置
      let deg = 30; // 旋转角度
      // let radianx = (deg * Math.PI) / 180; // 将角度转换为弧度

      function render() {
        /*
                      float radianx = radians(10.0); // 旋转角度
              float sinb = sin(radianx);
              float cosb = cos(radianx);
              // 绕x轴旋转的4维旋转矩阵
              mat4 rotatex = mat4(
                1.0, 0.0, 0.0, 0.0,
                0.0, cosb, -sinb, 0.0,
                0.0, sinb, cosb, 0.0,
                0.0, 0.0, 0.0, 1.0 // 4维齐次坐标
              );
              float radiany = radians(10.0); // 旋转角度
              sinb = sin(radiany);
              cosb = cos(radiany);
              // 绕y轴旋转的4维旋转矩阵
              mat4 rotatey = mat4(
                cosb, 0.0, -sinb, 0.0,
                0.0, 1.0, 0.0, 0.0,
                sinb, 0.0, cosb, 0.0,
                0.0, 0.0, 0.0, 1.0 // 4维齐次坐标
              );
              */
        deg += 0.1; // 每帧增加旋转角度
        const sinb = Math.sin((deg * Math.PI) / 180); // 计算正弦值
        const cosb = Math.cos((deg * Math.PI) / 180); // 计算余弦值
        gl.uniformMatrix4fv(
          u_x_matrix,
          false,
          new Float32Array([
            1.0,
            0.0,
            0.0,
            0.0,
            0.0,
            cosb,
            -sinb,
            0.0,
            0.0,
            sinb,
            cosb,
            0.0,
            0.0,
            0.0,
            0.0,
            1.0, // 绕x轴旋转的4维旋转矩阵
          ])
        );
        gl.uniformMatrix4fv(
          u_y_matrix,
          false,
          new Float32Array([
            cosb,
            0.0,
            -sinb,
            0.0,
            0.0,
            1.0,
            0.0,
            0.0,
            sinb,
            0.0,
            cosb,
            0.0,
            0.0,
            0.0,
            0.0,
            1.0, // 绕y轴旋转的4维旋转矩阵
          ])
        );
        for (let i = 0; i < faceColors.length; i++) {
          gl.uniform4fv(uColor, faceColors[i]);
          gl.drawElements(
            gl.TRIANGLES,
            6,
            gl.UNSIGNED_SHORT,
            i * 6 * Uint16Array.BYTES_PER_ELEMENT
          );
        }
        window.requestAnimationFrame(render); // 请求下一帧动画
      }
      render(); // 启动动画循环
    </script>
  </body>
</html>
